package org.android;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import org.helloroad.Contact;
import org.helloroad.Trip;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.util.Log;

/**
 * Embeds all the possible calls to the Webservice
 * 
 * @author adrien
 * 
 */
public class WSCommunicator {
	private static final String NAMESPACE = "http://10.0.2.2/";
	private static final String URL = "http://10.0.2.2/WS/ws.php";

	/**
	 * Check if the username/password match a valid user
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	public static Integer isValidLogin(String username, String password) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE, "doLogin");
		request.addProperty("uname", username);
		request.addProperty("upwd", password);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = envelope.getResponse();

			if (Integer.parseInt(resultObject.toString()) == 0) {
				return -1;
			} else {
				return Integer.parseInt(resultObject.toString());
			}

		} catch (Exception e) {
			Log.e("LOGIN", e.toString());
			return -1;
		}
	}

	/**
	 * Perform a new user registration. Returns 0 if error
	 * 
	 * @param username
	 * @param password
	 * @return Integer (0 if error)
	 */
	public static Integer registerUser(String username, String password) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doRegister");
		request.addProperty("uname", username);
		request.addProperty("upwd", password);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = envelope.getResponse();

			if (!resultObject.toString().equals("0")) {
				Log.v("REGISTER USER", resultObject.toString());
				return Integer.parseInt(resultObject.toString());
			} else
				Log.v("REGISTER USER", "Error");
			return 0;
		} catch (Exception e) {
			Log.e("REGISTER USER", e.toString());
			return 0;
		}
	}

	/**
	 * Retrieve data about a trip
	 * 
	 * @param id
	 * @return
	 */
	public static Trip getTripInfo(Integer id) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doGetTripInfo");
		request.addProperty("id", id);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET Trip INFO", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			SoapObject resultObject = (SoapObject) envelope.getResponse();
			return new Trip(resultObject);
		} catch (Exception e) {
			Log.e("GET TRIP INFO", e.toString());
			return null;
		}
	}

	/**
	 * Retrieve data about a contact
	 * 
	 * @param id
	 * @return
	 */
	public static Contact getContactInfo(Integer id) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doGetUserInfo");
		request.addProperty("id", id);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET user INFO", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			SoapObject resultObject = (SoapObject) envelope.getResponse();
			return new Contact(resultObject);
		} catch (Exception e) {
			Log.e("GET u INFO", e.toString());
			return null;
		}
	}

	/**
	 * Retrieve data about a contact
	 * 
	 * @param id
	 * @return
	 */
	public static Contact getContactInfo(String login) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doGetUserByLogin");
		request.addProperty("login", login);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET user INFO", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			SoapObject resultObject = (SoapObject) envelope.getResponse();
			return new Contact(resultObject);
		} catch (Exception e) {
			Log.e("GET u INFO", e.toString());
			return null;
		}
	}

	/**
	 * Retrieve data about a contact
	 * 
	 * @param id
	 * @return
	 */
	public static Integer updateUserInfo(Integer id, String firstname,
			String lastname, String number, String address) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doUpdateUserInfo");
		request.addProperty("id", id);
		request.addProperty("first", firstname);
		request.addProperty("last", lastname);
		request.addProperty("number", number);
		request.addProperty("address", address);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET user INFO", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			return 1;
		} catch (Exception e) {
			Log.e("GET u INFO", e.toString());
			return 2;
		}
	}

	/**
	 * Add a new trip, as registered by user_id
	 * 
	 * @param String
	 *            from
	 * @param String
	 *            to
	 * @param Integer
	 *            user_id
	 * @return Integer trip_ip
	 */
	public static Integer addTrip(String from, String to, Integer user_id,
			String date, HashMap<String, Boolean> days, String time,
			boolean isDriver) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doAddTrip");

		request.addProperty("from", from);
		request.addProperty("to", to);
		request.addProperty("user_id", user_id);
		request.addProperty("date", date);
		request.addProperty("time", time);

		if (isDriver)
			request.addProperty("driver_id", user_id);
		else
			request.addProperty("driver_id", null);

		if (days != null) {
			request.addProperty("monday", days.get("monday"));
			request.addProperty("tuesday", days.get("tuesday"));
			request.addProperty("wednesday", days.get("wednesday"));
			request.addProperty("thursday", days.get("thursday"));
			request.addProperty("friday", days.get("friday"));
			request.addProperty("saturday", days.get("saturday"));
			request.addProperty("sunday", days.get("sunday"));
		}

		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("ADD TRIP", "Request is ready, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = (Object) envelope.getResponse();
			Log.v("ADD TRIP", resultObject.toString());
			return Integer.parseInt(resultObject.toString());
		} catch (Exception e) {
			Log.e("ADD TRIP", e.toString());
			return -1;
		}
	}

	/**
	 * 
	 * @param from
	 * @param to
	 * @param user_id
	 * @return
	 */
	public static Integer addContact(Integer userId, Integer contactId) {
		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doAddContact");
		request.addProperty("user_id", userId);
		request.addProperty("contact_id", contactId);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("ADD CONTACT", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			@SuppressWarnings("unused")
			Object resultObject = (Object) envelope.getResponse();
			return 1;
		} catch (Exception e) {
			Log.e("ADD CONTACT", e.toString());
			return -1;
		}
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<Trip> getListOfTrips(Integer userId) {
		ArrayList<Trip> list = new ArrayList<Trip>();

		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doGetListOfTrips");
		request.addProperty("user_id", userId);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET LIST OF TRIPS", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = (Object) envelope.getResponse();
			Vector<Object> ml = (Vector<Object>) resultObject;

			for (Integer i = 0; i < ml.size(); i++) {
				if (ml.elementAt(i) != null) {
					SoapObject o = (SoapObject) ml.elementAt(i);
					list.add(new Trip(o));
				}
			}

			return list;
		} catch (Exception e) {
			Log.e("GET LIST OF TRIPS", e.toString());
			return list;
		}
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<Trip> search(String from, String to, String date,
			String time) {
		ArrayList<Trip> list = new ArrayList<Trip>();

		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doSearch");
		request.addProperty("from", from);
		request.addProperty("to", to);
		request.addProperty("date", date);
		request.addProperty("time", time);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("SEARCH TRIPS", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = (Object) envelope.getResponse();
			Vector<Object> ml = (Vector<Object>) resultObject;

			for (Integer i = 0; i < ml.size(); i++) {
				if (ml.elementAt(i) != null) {
					SoapObject o = (SoapObject) ml.elementAt(i);
					list.add(new Trip(o));
				}
			}

			return list;
		} catch (Exception e) {
			Log.e("SEARCH TRIPS", e.toString());
			return list;
		}
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<Trip> searchByDays(String from, String to,
			HashMap<String, Boolean> days, String time) {
		ArrayList<Trip> list = new ArrayList<Trip>();

		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doSearchByDays");
		if (days != null) {
			request.addProperty("from", from);
			request.addProperty("to", to);
			request.addProperty("mo", days.get("monday"));
			request.addProperty("tu", days.get("tuesday"));
			request.addProperty("we", days.get("wednesday"));
			request.addProperty("th", days.get("thursday"));
			request.addProperty("fr", days.get("friday"));
			request.addProperty("sa", days.get("saturday"));
			request.addProperty("su", days.get("sunday"));
		}
		request.addProperty("time", time);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("SEARCH TRIPS BY DAYS", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = (Object) envelope.getResponse();
			Vector<Object> ml = (Vector<Object>) resultObject;

			for (Integer i = 0; i < ml.size(); i++) {
				if (ml.elementAt(i) != null) {
					SoapObject o = (SoapObject) ml.elementAt(i);
					list.add(new Trip(o));
				}
			}

			return list;
		} catch (Exception e) {
			Log.e("SEARCH TRIPS BY DAYS", e.toString());
			return list;
		}
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<Contact> getListOfContacts(Integer userId) {
		ArrayList<Contact> list = new ArrayList<Contact>();

		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doGetListOfContacts");
		request.addProperty("user_id", userId);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET LIST OF CONTACTS", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = (Object) envelope.getResponse();
			Vector<Object> ml = (Vector<Object>) resultObject;

			for (Integer i = 0; i < ml.size(); i++) {
				if (ml.elementAt(i) != null) {
					SoapObject o = (SoapObject) ml.elementAt(i);
					list.add(new Contact(o));
				}
			}

			return list;
		} catch (Exception e) {
			Log.e("GET LIST OF CONTACTS", e.toString());
			return list;
		}
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<String> doGetLocations() {
		ArrayList<String> list = new ArrayList<String>();

		SoapObject request = new SoapObject(WSCommunicator.NAMESPACE,
				"doGetLocations");
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE transport = new HttpTransportSE(WSCommunicator.URL);
		Log.i("GET LIST OF CONTACTS", "Requete prete, call...");

		try {
			transport.call(WSCommunicator.URL, envelope);
			Object resultObject = (Object) envelope.getResponse();
			Vector<Object> ml = (Vector<Object>) resultObject;
			for (Integer i = 0; i < ml.size(); i++) {
				if (ml.elementAt(i) != null) {
					SoapObject o = (SoapObject) ml.elementAt(i);
					list.add(o.getProperty("name").toString());
				}
			}
			return list;
		} catch (Exception e) {
			Log.e("GET LIST OF CONTACTS", e.toString());
			return list;
		}
	}
}
